package hikvision

import (
	"bytes"
	"encoding/xml"
	"errors"
	"io"
	"net/http"
)

func GET(host, res string) ([]byte, error) {
	// 尝试读取数据
	body, err := tryGET(host, res)
	if err != nil {
		return nil, err
	}

	// 判断：是否未登录
	var userCheck UserCheck
	err = xml.Unmarshal(body, &userCheck)
	if err != nil {
		return body, nil
	}
	if userCheck.StatusValue != http.StatusUnauthorized {
		return body, nil
	}

	// 尝试登录
	err = tryLogin(host)
	if err != nil {
		return nil, err
	}

	return tryGET(host, res)
}

func tryGET(host, res string) ([]byte, error) {
	client, err := Client.GetClient(host)
	if err != nil || client == nil {
		return nil, err
	}

	// 创建请求
	req, err := http.NewRequest("GET", host+res, nil)
	if err != nil {
		return nil, err
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return data, nil
}

func tryLogin(host string) error {
	// 尝试登录
	Client.ResetClient(host)
	body, err := tryGET(host, "/ISAPI/Security/userCheck")
	if err != nil {
		Client.ResetClient(host)
		return err
	}

	// 解析返回数据
	var userCheck UserCheck
	err = xml.Unmarshal(body, &userCheck)
	if err != nil {
		Client.ResetClient(host)
		return err
	}
	if userCheck.StatusValue != http.StatusOK {
		Client.ResetClient(host)
		return errors.New(string(body))
	}

	return nil
}

func POST(host, res string, body []byte) ([]byte, error) {
	// 尝试读取数据
	body, err := tryPOST(host, res, body)
	if err != nil {
		return nil, err
	}

	// 判断：是否未登录
	var userCheck UserCheck
	err = xml.Unmarshal(body, &userCheck)
	if err != nil {
		return body, nil
	}
	if userCheck.StatusValue != http.StatusUnauthorized {
		return body, nil
	}

	// 尝试登录
	err = tryLogin(host)
	if err != nil {
		return nil, err
	}

	return tryPOST(host, res, body)
}

func tryPOST(host, res string, body []byte) ([]byte, error) {
	client, err := Client.GetClient(host)
	if err != nil || client == nil {
		return nil, err
	}

	// 创建请求
	req, err := http.NewRequest("POST", host+res, bytes.NewBuffer(body))
	if err != nil {
		return nil, err
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return data, nil
}
